﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Configuration.Install;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.ServiceProcess;
using Toolbox.Configuration;
using Toolbox.Plugin;
using System.Collections.ObjectModel;

namespace Toolbox
{
    public partial class Service : ServiceBase, ISupportInitialize
    {
        public static void StartService(Component component, params string[] args)
        {
            if (System.Environment.UserInteractive)
            {
                foreach (string a in args)
                {
                    switch (a)
                    {
                        case "--help":
                            return;

                        case "--install":
                            ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetEntryAssembly().Location });
                            return;

                        case "--uninstall":
                            ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetEntryAssembly().Location });
                            return;
                    }
                }

                if (component is Service)
                {
                    (component as Service).OnStart(null);
                }
            }
            else
            {
                if (component is Service)
                {
                    ServiceBase.Run(component as Service);
                }
            }
        }

        [ImportMany(AllowRecomposition=true)]
        [Browsable(false)]
        public IEnumerable<ExportFactory<IPluginThread>> Threads { get; set; }

        [ImportMany]
        public PluginInstances<IPluginThread> TestThread { get; set; }

        [Category("Configuration")]
        [Description("Plugin Location Provider")]
        [DisplayName("Plugin Location")]
        public ConfigurationProvider PluginLocation { get; set; }

        [Category("Configuration")]
        [Description("Threads Configuration Provider")]
        [DisplayName("Threads Configuration")]
        public ConfigurationProvider ThreadConfiguration { get; set; }

        public Service()
        {
            // Init
            InitializeComponent();
        }

        public void BeginInit()
        {
            if (!this.DesignMode)
            {

            }
        }

        public void EndInit()
        {
            if (!this.DesignMode)
            {
                Uri log;
                if (Uri.TryCreate(this.ThreadConfiguration.Settings.Value(this.ThreadConfiguration.Entry + "/EventLog"), UriKind.Absolute, out log))
                {
                    this.EventLog.MachineName = log.Host;
                    this.EventLog.Log = log.LocalPath.Substring(1);
                    this.EventLog.Source = log.Fragment.Length > 1 ? log.Fragment.Substring(1) : this.EventLog.Source;
                }

                try
                {
                    int size = this.ThreadConfiguration.GetSize();

                    for (int i = 0; i < size; i++)
                    {
                        this.ThreadConfiguration.Index = i+1;
                        this.TestThread.Init(this.ThreadConfiguration.GetArrayValuesAsUri());
                    }

                    //this.LoadedThreads = Plugin.Plugin.Init<IPluginThread>(this.Threads, this.ThreadConfiguration);
                }
                catch (Exception e)
                {
                    if (this.EventLog is EventLog)
                    {
                        //this.EventLog.WriteEntry("Cannot initialize plugin " + name + ((e.InnerException is Exception) ? (":\n" + e.InnerException.Message) : ""), EventLogEntryType.Error);
                    }
                }


            }
        }

        protected override void OnStart(string[] args)
        {
            if (this.EventLog is EventLog)
            {
                this.EventLog.WriteEntry("Starting in " + Directory.GetCurrentDirectory() + "...");
            }

            foreach (IPluginThread p in this.TestThread.Values)
            {
                if (!p.IsRunning)
                {
                    p.Start();
                }
            }
        }

        protected override void OnContinue()
        {
            foreach (IPluginThread p in this.TestThread.Values)
            {
                if (p.IsRunning)
                {
                    p.Start();
                }
            }
        }

        protected override void OnPause()
        {
            foreach (IPluginThread p in this.TestThread.Values)
            {
                if (p.IsRunning)
                {
                    p.Pause();
                }
            }
        }

        protected override void OnStop()
        {
            if (this.EventLog is EventLog)
            {
                this.EventLog.WriteEntry("Stopping...");
            }

            foreach (IPluginThread p in this.TestThread.Values)
            {
                if (p.IsRunning)
                {
                    p.Stop();
                }
            }
        }


        public override object InitializeLifetimeService()
        {
            return null;
        }




    }
}


